// CW32Window.cpp : Defines the exported functions for the DLL application.
//


#include <Windows.h>
#include <WindowsX.h>
#include "CW32Window.h"
#include <Python.h>
#include "CXX/CW32Window_wrap.cxx"
#include "CDataObject.h"
#include <ShlObj.h>

const wchar_t MUI_CLIP_FORMAT[] = L"mui_clip_info";

CW32Window::CW32Window() : CBaseWnd()
{
	m_dwFeedbackEffect = 0;
}
CW32Window::~CW32Window()
{


}
HRESULT CW32Window::Create(HWND hwndParent, UINT wndWidth, UINT wndHeight, const WCHAR* pWndName, UINT classStyle , UINT windowStyle , UINT windowExStyle, int winPosX, int winPosY )
{
	HRESULT hr = CBaseWnd::Create(hwndParent, wndWidth, wndHeight, pWndName, classStyle, windowStyle, windowExStyle, winPosX, winPosY);
	if (SUCCEEDED(hr))
	{
		hr = RegisterDragDrop(m_hWnd, this);
		if (FAILED(hr))
			assert(hr);
	}
	return hr;
}
LRESULT CW32Window::OnMouseMessage(UINT message, int xPos, int yPos, int dx, int dy, int zDelta, int keyState)
{
	if (message == WM_MOUSEMOVE)
	{
		if (!(xPos == m_preMouseX && yPos == m_preMouseY))
		{
			PyObject* pcallback = GetCallback("MOUSEMOVE");
			if (pcallback != NULL)
				CallPyMethod(pcallback, "iiii", xPos, yPos, dx, dy);
		}
	}
	else if (message == WM_LBUTTONDOWN)
	{
		PyObject* pcallback = GetCallback("LBUTTONDOWN");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_LBUTTONUP)
	{
		PyObject* pcallback = GetCallback("LBUTTONUP");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_LBUTTONDBLCLK)
	{
		PyObject* pcallback = GetCallback("LBUTTONDBLCLK");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_RBUTTONDOWN)
	{
		PyObject* pcallback = GetCallback("RBUTTONDOWN");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_RBUTTONUP)
	{
		PyObject* pcallback = GetCallback("RBUTTONUP");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_RBUTTONDBLCLK)
	{
		PyObject* pcallback = GetCallback("RBUTTONDBLCLK");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_MBUTTONDOWN)
	{
		PyObject* pcallback = GetCallback("MBUTTONDOWN");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_MBUTTONUP)
	{
		PyObject* pcallback = GetCallback("MBUTTONUP");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_MBUTTONDBLCLK)
	{
		RECT* pRECT = new RECT;
		pRECT->left =99;
		pRECT->top =199;
		pRECT->bottom = 299;
		pRECT->right = 399;
		
		//SWIG_Python_NewPointerObj(NULL, )
		PyObject* pcallback = GetCallback("MBUTTONDBLCLK");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "ii", xPos, yPos);
	}
	else if (message == WM_MOUSEWHEEL)
	{
		PyObject* pcallback = GetCallback("MOUSEWHEEL");
		if (pcallback != NULL)
			CallPyMethod(pcallback, "iiii", xPos, yPos, zDelta, keyState );
	}
	else if (message == WM_MOUSELEAVE)
	{
		PyObject* pcallback = GetCallback("MOUSELEAVE");
		if (pcallback != NULL)
			CallPyMethod(pcallback, NULL);
	}
	return 0;
}
BOOL CW32Window::_ProcKeyMsg(UINT message, UINT nChar, UINT nRepCnt)
{
	UINT modifiers = 0;
	BOOL bIsShitKeyDown = FALSE;
	BOOL bIsCtrlKeyDown = FALSE;
	BOOL bIsAltKeyDown  = FALSE;
	BOOL bIsWinKeyDown  = FALSE;
	BOOL bIsCapsLocked  = FALSE;
	
	SHORT st = GetKeyState(VK_SHIFT);
	if(st & 0x1000)
	{
		bIsShitKeyDown = TRUE;
		modifiers |= MOD_SHIFT; 
	}
	st = GetKeyState(VK_CONTROL);
	if(st & 0x1000)
	{
		bIsCtrlKeyDown = TRUE;
		modifiers |= MOD_CTRL; 
	}
	st = GetKeyState(VK_MENU);
	if(st & 0x1000)
	{
		bIsAltKeyDown = TRUE;
		modifiers |= MOD_ALT;
	}
	st = GetKeyState(VK_LWIN);
	if(st & 0x1000)
	{
		bIsWinKeyDown = TRUE;
		modifiers |= MOD_WINDOWS;
	}
	st = GetKeyState(VK_RWIN);
	if(st & 0x1000)
	{
		bIsWinKeyDown = TRUE;
		modifiers |= MOD_WINDOWS;
	}
	st = GetKeyState(VK_CAPITAL);
	if(st & 0x0001)
	{
		bIsCapsLocked = TRUE;
		modifiers |= MOD_CAPSLOCK;
	}
	st = GetKeyState(VK_NUMLOCK);
	if(st & 0x0001)
	{
		bIsCapsLocked = TRUE;
		modifiers |= MOD_NUMLOCK;
	}
	PyObject* pCallback = NULL;
	if (message == WM_SYSKEYUP)
	{
		pCallback = GetCallback("KEYUP");
	}
	else if (message == WM_SYSKEYDOWN)
	{
		pCallback = GetCallback("KEYDOWN");
	}
	else if (message == WM_KEYDOWN)
	{
		pCallback = GetCallback("KEYDOWN");
	}
	else if (message == WM_KEYUP)
	{
		pCallback = GetCallback("KEYUP");
	}
	else if (message == WM_CHAR)
	{
		pCallback = GetCallback("CHAR");
	}
	if (pCallback != NULL)
	{
		for (UINT i =0; i < nRepCnt; i++)
		{
			CallPyMethod(pCallback, "ii", nChar, modifiers);
		}
	}
	
	return TRUE;
}

LRESULT CW32Window::OnKeyboardMessage(UINT message, UINT nChar, UINT nRepCnt)
{	
	return _ProcKeyMsg(message, nChar, nRepCnt);
}
LRESULT CW32Window::OnActivate(UINT actType, BOOL bMinimize, long hwnd)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("ACTIVATE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, "Iii", actType, bMinimize, hwnd);
	}
	return 1;
}
LRESULT CW32Window::OnActivateApp(BOOL bActivate, long hThread)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("ACTIVATEAPP");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, "ii", bActivate, hThread);
	}
	return 1;
}
LRESULT CW32Window::OnClose()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("CLOSE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnPaint()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("PAINT");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnCreate(CREATESTRUCT* pCreateInfo)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("CREATE");
	if (pCallback != NULL)
	{
		PyObject* pyCreateInfo = NULL;
		pyCreateInfo = SWIG_NewPointerObj(SWIG_as_voidptr(pCreateInfo), SWIGTYPE_p_CREATESTRUCT , SWIG_POINTER_NEW |  0 );
		CallPyMethod(pCallback, "O", pyCreateInfo);
		Py_XDECREF(pyCreateInfo);
	}
	
	return 1;
}
LRESULT CW32Window::OnDestory()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("DESTORY");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	HRESULT hr = S_OK;
	hr = RevokeDragDrop(m_hWnd);
	if (FAILED(hr))
		assert(0);
	return 1;
}
LRESULT CW32Window::OnEnable(BOOL bEnable)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("ENABLE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, "i", bEnable);
	}
	return 1;
}
LRESULT CW32Window::OnEnterSizeMove()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("ENTERSIZEMOVE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnExitSizeMove()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("EXITSIZEMOVE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnGetMinMaxInfo(MINMAXINFO* pInfo)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("GETMINMAXINFO");
	if (pCallback != NULL)
	{
		PyObject* pyInfo = NULL;
		pyInfo = SWIG_NewPointerObj(SWIG_as_voidptr(pInfo), SWIGTYPE_p_MINMAXINFO , SWIG_POINTER_NEW |  0 );
		CallPyMethod(pCallback, "O", pyInfo);
		//Py_XDECREF(pyInfo);
	}

	return 1;
}

LRESULT CW32Window::OnMove(int x, int y)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("MOVE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, "ii", x, y);
	}
	return 1;
}
LRESULT CW32Window::OnMoving(RECT* prect)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("MOVING");
	if (pCallback != NULL)
	{
		int x = prect->left;
		int y = prect->top;
		CallPyMethod(pCallback, "ii", x, y);
		//Py_XDECREF(pyRect);
	}
	return 1;
}
LRESULT CW32Window::OnNCActivate(BOOL bActivate, long hRgn)
{	
	PyObject* pCallback = NULL;
	pCallback = GetCallback("NCACTIVATE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, "ii", bActivate, hRgn);
	}
	return 1;
}
LRESULT CW32Window::OnNCCreate(CREATESTRUCT* pCreateInfo)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("NCCREATE");
	if (pCallback != NULL)
	{
		PyObject* pyCreateInfo = NULL;
		pyCreateInfo = SWIG_NewPointerObj(SWIG_as_voidptr(pCreateInfo), SWIGTYPE_p_CREATESTRUCT , SWIG_POINTER_NEW |  0 );
		CallPyMethod(pCallback, "O", pyCreateInfo);
		//Py_XDECREF(pyCreateInfo);
	}

	return 1;
}
LRESULT CW32Window::OnNCDestory()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("NCDESTORY");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnNullMessage()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("NULLMSG");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnQuit(int nExitCode)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("QUIT");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, "i", nExitCode);
	}
	return 1;
}
LRESULT CW32Window::OnCancelMode()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("CANCELMODE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnQueryDragIcon()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("QUERYDRAGICON");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnQueryOpen()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("QUERYDRAGOPEN");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnShowWindow(BOOL bShow, UINT status)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("SHOWWINDOW");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, "iI", bShow, status);
	}
	return 1;
}
LRESULT CW32Window::OnSize(UINT width, UINT height, UINT nFlag)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("SIZE");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, "III", width, height, nFlag);
	}
	return 1;
}
LRESULT CW32Window::OnSizing(RECT* pRect, UINT nFlag)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("SIZING");
	if (pCallback != NULL)
	{
		int width = pRect->right - pRect->left;
		int height = pRect->bottom - pRect->top;
		CallPyMethod(pCallback, "III", width, height, nFlag);
		//Py_XDECREF(pyRect);

	}
	return 1;
}
LRESULT CW32Window::OnStyleChanged(int styleType, STYLESTRUCT* pStyleInfo)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("STYLECHANGED");
	if (pCallback != NULL)
	{
		PyObject* pyStyleInfo = NULL;
		pyStyleInfo = SWIG_NewPointerObj(SWIG_as_voidptr(pStyleInfo), SWIGTYPE_p_STYLESTRUCT, SWIG_POINTER_NEW |  0 );
		CallPyMethod(pCallback, "iO", styleType, pyStyleInfo);
		//Py_XDECREF(pyStyleInfo);
	}
	return 1;
}
LRESULT CW32Window::OnStyleChanging(int styleType, STYLESTRUCT* pStyleInfo)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("STYLECHANGING");
	if (pCallback != NULL)
	{
		PyObject* pyStyleInfo = NULL;
		pyStyleInfo = SWIG_NewPointerObj(SWIG_as_voidptr(pStyleInfo), SWIGTYPE_p_STYLESTRUCT, SWIG_POINTER_NEW |  0 );
		CallPyMethod(pCallback, "iO", styleType, pyStyleInfo);
		//Py_XDECREF(pyStyleInfo);
	}
	return 1;
}
LRESULT CW32Window::OnThemeChanged()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("THEMECHANGED");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnUserChanged()
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("USERCHANGED");
	if (pCallback != NULL)
	{
		CallPyMethod(pCallback, NULL);
	}
	return 1;
}
LRESULT CW32Window::OnWindowPosChanged(WINDOWPOS* pwndPos)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("WINDOWPOSCHANGED");
	if (pCallback != NULL)
	{
		PyObject* pyWndPos = NULL;
		pyWndPos = SWIG_NewPointerObj(SWIG_as_voidptr(pwndPos), SWIGTYPE_p_WINDOWPOS, SWIG_POINTER_NEW |  0 );
		CallPyMethod(pCallback, "O", pyWndPos);
		//Py_XDECREF(pyWndPos);
	}
	return 1;
}
LRESULT CW32Window::OnWindowPosChanging(WINDOWPOS* pwndPos)
{
	PyObject* pCallback = NULL;
	pCallback = GetCallback("WINDOWPOSCHANGING");
	if (pCallback != NULL)
	{
		PyObject* pyWndPos = NULL;
		pyWndPos = SWIG_NewPointerObj(SWIG_as_voidptr(pwndPos), SWIGTYPE_p_WINDOWPOS, SWIG_POINTER_NEW |  0 );
		CallPyMethod(pCallback, "O", pyWndPos);
		//Py_XDECREF(pyWndPos);
	}
	return 1;
}

//////////// Drag and Drop////////////
DWORD CW32Window::QuertyDropEffect(DWORD dwKeyState, POINTL* pt)
{
	POINT pnt;
	pnt.x = pt->x;
	pnt.y = pt->y;
	::ScreenToClient(m_hWnd, &pnt);
	PyObject* pCallback = NULL;
	pCallback = GetCallback("QueryDropEffect");
	if (pCallback != NULL)
	{
		PyObject* ret_val = CallPyMethod_withRet(pCallback, "ii", pnt.x, pnt.y);
		DWORD dropeffect = 0;
		if (ret_val != NULL && ret_val != Py_None) {
			PyArg_Parse(ret_val, "i", &dropeffect);
			Py_XDECREF(ret_val);
		}
		return dropeffect;
	}
	return 0;
}

void CW32Window::DoDragDrop(const WCHAR* files, UINT lens, const char* muiClipInfo, UINT muiClipLen,
						  BOOL allowMove, BOOL allowCopy)
{
	DWORD dwEffect;
	
	CDataObject* pdobj = new CDataObject();	
	if( pdobj )
	{
		if( lens > 0 )
		{
			FORMATETC fmtetc = {0};
			fmtetc.cfFormat = CF_HDROP;
			fmtetc.dwAspect = DVASPECT_CONTENT;
			fmtetc.lindex = -1;
			fmtetc.tymed = TYMED_HGLOBAL;

			STGMEDIUM medium = {0};
			medium.tymed = TYMED_HGLOBAL;
			medium.hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeof(DROPFILES) + lens * sizeof(WCHAR)); //for NULL

			char* pMem = (char*)GlobalLock(medium.hGlobal);
			DROPFILES* dropfiles = (DROPFILES*)pMem;
			dropfiles->pFiles = sizeof(DROPFILES);
			::GetCursorPos(&dropfiles->pt);
			dropfiles->fNC = FALSE;
			dropfiles->fWide = 1;
			pMem = pMem + sizeof(DROPFILES);
			memcpy(pMem,files, lens * sizeof(WCHAR));
			GlobalUnlock(medium.hGlobal);
			pdobj->SetData(&fmtetc,&medium,TRUE);

		}

		// mui clipboard info
		if (muiClipLen != 0)
		{
			UINT muiClipID = ::RegisterClipboardFormat(MUI_CLIP_FORMAT);
			if (muiClipID != 0)
			{
				FORMATETC muiFmtetc = {0};
				muiFmtetc.cfFormat = muiClipID;
				muiFmtetc.dwAspect = DVASPECT_CONTENT;
				muiFmtetc.lindex = -1;
				muiFmtetc.tymed = TYMED_HGLOBAL;

				STGMEDIUM muiMedium = {0};
				muiMedium.tymed = TYMED_HGLOBAL;
				muiMedium.hGlobal = GlobalAlloc(GMEM_MOVEABLE, muiClipLen);

				char* pMem = (char*)GlobalLock(muiMedium.hGlobal);
				memcpy(pMem, muiClipInfo, muiClipLen);
				GlobalUnlock(muiMedium.hGlobal);
				pdobj->SetData(&muiFmtetc,&muiMedium,TRUE);
			}
		}

		HWND oldWnd = ::SetCapture(m_hWnd);
		DWORD OKEffects = DROPEFFECT_SCROLL;
		if (allowMove)
			OKEffects |= DROPEFFECT_MOVE;
		if (allowCopy)
			OKEffects |= DROPEFFECT_COPY;
		HRESULT hr = ::DoDragDrop(
			pdobj, dynamic_cast<IDropSource*>(this),
			OKEffects,
			&dwEffect
			);
		::SetCapture(oldWnd);
		pdobj->Release();
	}
	
}
HRESULT CW32Window::GiveFeedback(DWORD dwEffect)
{
	m_dwFeedbackEffect = dwEffect;
	return DRAGDROP_S_USEDEFAULTCURSORS;
}

HRESULT CW32Window::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
{
	if (fEscapePressed)
		return DRAGDROP_S_CANCEL;

	else if ((grfKeyState & MK_LBUTTON) && (grfKeyState & MK_RBUTTON))
	{
		return DRAGDROP_S_CANCEL;
	}
	else if (!(grfKeyState & (MK_LBUTTON | MK_RBUTTON)))
	{
		if (m_dwFeedbackEffect == 0)
			return DRAGDROP_S_CANCEL;
		PyObject* pcallback = GetCallback("COMPLETE_DROP");
		PyObject* ret_val = NULL;
		if (pcallback != NULL)
		{
			ret_val = CallPyMethod_withRet(pcallback, NULL);
		}
		if (ret_val)
		{
			int succeeded = 0;
			PyArg_Parse(ret_val, "i", &succeeded);
			Py_XDECREF(ret_val);
			if (succeeded)
				return DRAGDROP_S_DROP;   // complete the drag and drop operation
		}
		return DRAGDROP_S_CANCEL;
	}
	return S_OK;
}

HRESULT CW32Window::QueryInterface(REFIID riid, void **ppv)
{
	if(IsEqualIID(riid, IID_IUnknown))
	{
		*ppv = static_cast<IDropTarget*>(this);
		AddRef();
		return NOERROR;
	}
	else if(IsEqualIID(riid, IID_IDropSource))
	{
		*ppv = static_cast<IDropSource*>(this);
		AddRef();
		return NOERROR;
	}
	else if(IsEqualIID(riid, IID_IDropTarget))
	{
		*ppv = static_cast<IDropTarget*>(this);
		AddRef();
		return NOERROR;
	}
	*ppv = NULL;
	return E_NOINTERFACE;
}
ULONG CW32Window::AddRef()
{
	return CRefCount::AddRef();
}
ULONG CW32Window::Release()
{
	return CRefCount::Release();
}

HRESULT CW32Window::DragEnter(IDataObject *lpdo, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
	
	UINT           uNumFiles = 0;
	HGLOBAL        hglobal = 0;
	HDROP          hdrop = 0;
	UINT           uLen = 0;
	WCHAR          *szItem = NULL;

	
	FORMATETC fmtetc = {0};
	fmtetc.cfFormat = CF_HDROP;
	fmtetc.dwAspect = DVASPECT_CONTENT;
	fmtetc.lindex = -1;
	fmtetc.tymed = TYMED_HGLOBAL;
	
	STGMEDIUM medium;
	lpdo->GetData(&fmtetc, &medium);
	hglobal = medium.hGlobal;
	m_lsDroppedFiles.clear();
	if ( NULL != hglobal )
	{
		hdrop = (HDROP) GlobalLock ( hglobal );

		uNumFiles = DragQueryFile ( hdrop, 0xFFFFFFFF, NULL, 0 );		

		for ( UINT uFile = 0; uFile < uNumFiles; uFile++ )
		{
			uLen = DragQueryFile ( hdrop, uFile, NULL, 0 );			
			szItem = new WCHAR[uLen+2];
			if ( 0 != DragQueryFile ( hdrop, uFile, szItem, uLen+2 ))
			{
				std::wstring _tmpStr = szItem;
				m_lsDroppedFiles.push_back(_tmpStr);
			}
			delete [] szItem;
		}
		GlobalUnlock ( hglobal );
	}

	if ( m_lsDroppedFiles.size() > 0 ) 
	{
		*pdwEffect = QuertyDropEffect(dwKeyState, &pt);
		return S_OK;
	}
	else
	{
		*pdwEffect = DROPEFFECT_NONE;
		return E_INVALIDARG;
	}
}
HRESULT CW32Window::DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
	if ( m_lsDroppedFiles.size() > 0 )
		*pdwEffect = QuertyDropEffect(dwKeyState, &pt);
	return S_OK;
}
HRESULT CW32Window::DragLeave()
{
	return S_OK;
}
HRESULT CW32Window::Drop( IDataObject *lpdo, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
	*pdwEffect = QuertyDropEffect(dwKeyState, &pt);

	std::wstring dropFiles;

	for( int p =0; p < m_lsDroppedFiles.size(); p++)
	{
		std::wstring strFileName = m_lsDroppedFiles[p];
		dropFiles += strFileName;
		if (p != m_lsDroppedFiles.size()-1)
			dropFiles += L"*";
	}
	m_lsDroppedFiles.clear();

	POINT pnt;
	pnt.x = pt.x;
	pnt.y = pt.y;
	::ScreenToClient(m_hWnd, &pnt);

	PyObject* pCallBack = GetCallback("onOleDropFiles");
	if (pCallBack != NULL)
	{
		CallPyMethod(pCallBack, "iiu", pnt.x, pnt.y, dropFiles.c_str());
	}
	
	return S_OK;
}